package com.css.fxfzcpxx.modules.certificateManage.service.impl;

import com.css.fxfzcpxx.base.attachment.entity.AttachmentInfoEntity;
import com.css.fxfzcpxx.base.attachment.service.AttachmentInfoService;
import com.css.fxfzcpxx.base.response.RestResponse;
import com.css.fxfzcpxx.base.user.service.UserService;
import com.css.fxfzcpxx.base.user.viewobjects.UserBaseInfoVO;
import com.css.fxfzcpxx.constants.YNEnum;
import com.css.fxfzcpxx.modules.certificateManage.entity.CertificateManage;
import com.css.fxfzcpxx.modules.certificateManage.entity.CertificateRule;
import com.css.fxfzcpxx.modules.certificateManage.entity.UserCertificate;
import com.css.fxfzcpxx.modules.certificateManage.repository.CertificateManageRepository;
import com.css.fxfzcpxx.modules.certificateManage.service.CertificateManageService;
import com.css.fxfzcpxx.modules.certificateManage.vo.CertificateRuleVo;
import com.css.fxfzcpxx.modules.certificateManage.vo.CertificateVo;
import com.css.fxfzcpxx.util.CreateGson;
import com.css.fxfzcpxx.util.PlatformObjectUtils;
import com.css.fxfzcpxx.util.StringUtils;
import com.css.fxfzcpxx.util.UUIDGenerator;
import com.css.fxfzcpxx.web.PlatformSessionContext;
import com.css.fxfzcpxx.zcpt.sys.entity.SUser;
import com.css.fxfzcpxx.zcpt.sys.service.impl.SUserServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.List;

@Service
public class CertificateManageServiceImpl implements CertificateManageService {

    @Resource
    CertificateManageRepository certificateManageRepository;

    @Autowired
    private AttachmentInfoService attachmentInfoService;
    @Resource
    SUserServiceImpl sUserServiceImpl;

    @Resource
    UserService userService;

    @Value("${image.localDir}")
    private String localDir;

    @Override
    public AttachmentInfoEntity preview(String fileName, CertificateVo certificateVo) throws IOException {
        // 读取原图片信息
        ClassPathResource resource = new ClassPathResource("template"+ File.separator+ fileName);
        InputStream inputStream = resource.getInputStream();
        //文件转化为图片
        Image srcImg = ImageIO.read(inputStream);
        //获取图片的宽、高
        int srcImgWidth = srcImg.getWidth(null);
        int srcImgHeight = srcImg.getHeight(null);
        // 加水印
        BufferedImage bufImg = new BufferedImage(srcImgWidth, srcImgHeight, BufferedImage.TYPE_INT_RGB);
        Graphics2D g = bufImg.createGraphics();
        g.drawImage(srcImg, 0, 0, srcImgWidth, srcImgHeight, null);
        // 证书中写字
        Date date = new Date();
        SimpleDateFormat format = new SimpleDateFormat("yyyy.MM.dd");
        String format1 = format.format(date);

        Font font = new Font("思源黑体", Font.BOLD, 22);
        FontMetrics metrics = g.getFontMetrics(font);
        int stringWidth = metrics.stringWidth(certificateVo.getCertificateName());
        // 字符打印的x坐标 = 矩形的起点坐标 + 字符居中打印情况下字符的边与矩形边的距离（可能是正，也可能是负数）
        int centerX = srcImgWidth / 2;
        int x = centerX - stringWidth / 2;
        //姓名
        if (!PlatformObjectUtils.isEmpty(certificateVo.getCertificateName())) {
            setMark(g, certificateVo.getCertificateName(), x, 237, font, Color.decode("#333333"), 800);
        }
        //内容
        if (!PlatformObjectUtils.isEmpty(certificateVo.getCertificateContent())) {
            setMark(g, certificateVo.getCertificateContent(), 65, 310, new Font("思源黑体", Font.HANGING_BASELINE, 12), Color.decode("#332e2e"), 600);
        }
        //优秀/合格
        if (!PlatformObjectUtils.isEmpty(certificateVo.getCertificateLevel())) {
            setMark(g, "“" + certificateVo.getCertificateLevel() + "”", 145, 360, new Font("思源黑体", Font.BOLD, 35), Color.decode("#F16937"), 800);
        }
        String color = "";
        if (fileName.equals("01.jpg")) {
            color = "#427755";
        } else if (fileName.equals("02.jpg")) {
            color = "#29466D";
        } else if (fileName.equals("03.jpg")) {
            color = "#BC9315";
        }
        setMark(g, format1, 175, 420, new Font("思源黑体", Font.BOLD, 12), Color.decode(color), 800);

        //画出水印
        g.dispose();

        OutputStream os = null;
        String dateDir = new SimpleDateFormat("/yyyy/MM/dd").format(new Date());
        String savePath = localDir + dateDir;

        File dir = new File(savePath);
        boolean mkdirs = false;
        // 判断地址是否存在。不存在则创建 需要注意的是 Mac创建的目录需要在二级目录 就好像/Users/tp/下才可以创建 所以你需要先有一个二级目录。如果直接在/Users/下创建 程序会报false 这个本人也没有去研究为什么
        if (!dir.exists() && !dir.isDirectory()) {
            mkdirs = dir.mkdirs();
            System.out.println(mkdirs);
        }

        String preFileName = fileName.substring(0, fileName.lastIndexOf("."));
        // .jpg  .pdf  .txt  .docs
        String fileType = fileName.substring(fileName.lastIndexOf("."));
        String realFileName = preFileName + "_" + System.currentTimeMillis() + "zsfj" + fileType;
        // 将流放到指定的目录
        os = new FileOutputStream(savePath + File.separator + realFileName);
        // 将生成图片水印的流文件输出到你的本地 复制
        ImageIO.write(bufImg, "jpg", os);
        List<AttachmentInfoEntity> attachmentInfoEntities = new ArrayList<>();
        AttachmentInfoEntity attachmentInfoEntity = buildAttachment(fileName, dateDir, realFileName);
        attachmentInfoEntities.add(attachmentInfoEntity);
        int save = attachmentInfoService.save(attachmentInfoEntities);
        os.close();
        if (save == 1) {
            return attachmentInfoEntity;
        }
        return null;
    }

    @Override
    public RestResponse previewDel(String id) {
        //查询是否有规则在使用该证书
        /*List<CertificateRuleVo> certificateRuleVos = certificateManageRepository.queryRule();*/
        CertificateRule certificateRule=certificateManageRepository.findRuleByCertificateId(id);
        if (PlatformObjectUtils.isEmpty(certificateRule)) {
            certificateManageRepository.previewDel(id);
            return RestResponse.succeed("成功");
        }else {
            return RestResponse.fail("该证书正在被授予规则使用");
        }

    }

    @Override
    public List<AttachmentInfoEntity> getCertificateFile() {

        return attachmentInfoService.getCertificateFile("zsfj.");
    }

    @Override
    public RestResponse save(CertificateManage certificateManage) {
        CertificateManage cM = certificateManageRepository.queryByName(certificateManage.getPictureName());
        if (null != cM) {
            return RestResponse.fail("模板" + cM.getPictureName() + "已经存在");
        }
        certificateManage.setId(UUID.randomUUID().toString().replaceAll("-", ""));
        certificateManage.setCreateTime(new Date());
        certificateManage.setCreateUser(PlatformSessionContext.getUserID());
        certificateManage.setDelFlag(YNEnum.N.toString());
        certificateManageRepository.save(certificateManage);
        return RestResponse.succeed();
    }

    //修改调用修改时生成证书图片
    @Override
    public void update(CertificateManage certificateManage) throws IOException {
        //查看是否有预览图
        if (!com.alibaba.druid.util.StringUtils.isEmpty(certificateManage.getCertificateFile())) {
            //获取文件路径
            List<AttachmentInfoEntity> attachmentInfoEntities = attachmentInfoService.queryFile(certificateManage.getCertificateFile());
            if (attachmentInfoEntities.size() != 0) {
                AttachmentInfoEntity attachmentInfoEntity = attachmentInfoEntities.get(0);
                //如果有则删除之前的图片
                Map<String, String> map = new HashMap<>();
                map.put("attachId", attachmentInfoEntity.getAttachId());
                attachmentInfoService.deleteFile(map);
                String fileName = localDir + attachmentInfoEntity.getAttachPath();
                File file = new File(fileName);
                // 如果文件路径只有单个文件
                if (file.exists() && file.isFile()) {
                    file.delete();
                }
            }
        }
        //生成图片
        CertificateVo certificateVo = new CertificateVo();
        //证书内容
        certificateVo.setCertificateContent(certificateManage.getCertificateContent());
        //证书等级优秀/良好
        certificateVo.setCertificateLevel(certificateManage.getCertificateLevel());
        //证书模板人员姓名
        certificateVo.setCertificateName("[姓名]");
        //生成图片
        AttachmentInfoEntity preview = preview(certificateManage.getPictureName(), certificateVo);
        //生成图片id
        certificateManage.setCertificateFile(preview.getAttachId());
        certificateManage.setUpdateTime(new Date());
        certificateManage.setUpdateUser(PlatformSessionContext.getUserID());
        certificateManageRepository.update(certificateManage);
    }

    //获取所有模板
    @Override
    public List<CertificateManage> queryAll() {
        return certificateManageRepository.queryAll();
    }

    //修改规则
    @Override
    public void updateRule(List<CertificateRule> ruleList) {
        certificateManageRepository.deleteRule();
        for(CertificateRule rule:ruleList){
            rule.setId(UUIDGenerator.getUUID());
            certificateManageRepository.saveRule(rule);
        }

    }

    //查询证书授予规则
    @Override
    public List<CertificateRuleVo> queryRule() {
        return certificateManageRepository.queryRule();
    }

    //根据姓名和模板生成证书
    @Override
    public String getCertificateId(String id, String userID) {
        CertificateManage byId=certificateManageRepository.findById(id);
        //获取用户名称
        String sUser = sUserServiceImpl.getSUser(userID);
        SUser userInfo = CreateGson.createGson().fromJson(sUser, SUser.class);
        String userName="";
        if(userInfo==null){
            UserBaseInfoVO user = userService.getUser(PlatformSessionContext.getUserID());
            userName=user.getUserName();
        }else{
            userName=userInfo.getUserName();
        }
        //生成图片
        CertificateVo certificateVo = new CertificateVo();
        //证书内容
        certificateVo.setCertificateContent(byId.getCertificateContent());
        //证书等级优秀/良好
        certificateVo.setCertificateLevel(byId.getCertificateLevel());
        //证书模板人员姓名
        certificateVo.setCertificateName(userName);
        String attid=null;
        //生成图片
        try {
            AttachmentInfoEntity preview = preview(byId.getPictureName(), certificateVo);
            attid=preview.getAttachId();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return attid;
    }

    //获取用户证书
    @Override
    public List<UserCertificate> getUserCertificate() {
        return certificateManageRepository.getUserCertificate(PlatformSessionContext.getUserID());
    }

    private AttachmentInfoEntity buildAttachment(String fileName, String dateDir, String realFileName) {
        AttachmentInfoEntity attachmentInfoEntity = new AttachmentInfoEntity();
        attachmentInfoEntity.setAttachId(StringUtils.buildPrimaryId());
        attachmentInfoEntity.setAttachName(fileName);
        attachmentInfoEntity.setAttachPath(dateDir + "/" + realFileName);
        attachmentInfoEntity.setFileDirId(localDir);
        attachmentInfoEntity.setIsValid("1");
        attachmentInfoEntity.setIsCompleted("1");
        return attachmentInfoEntity;
    }

    private void setMark(Graphics2D graphics2D, String context, Integer x, Integer y, Font font, Color color, Integer maxWidth) {
        // 设置字体
        graphics2D.setFont(font);
        // 设置颜色
        graphics2D.setColor(color);
       /* // 写字
        graphics2D.drawString(context, x, y);*/
        JLabel label = new JLabel(context);
        label.setFont(font);
        FontMetrics metrics = label.getFontMetrics(label.getFont());
        int textH = metrics.getHeight();
        int textW = metrics.stringWidth(label.getText()); //字符串的宽
        String tempText = context;

        while (textW > maxWidth) {
            int n = textW / maxWidth;
            int subPos = tempText.length() / n;
            String drawText = tempText.substring(0, subPos);
            int subTxtW = metrics.stringWidth(drawText);
            while (subTxtW > maxWidth) {
                subPos--;
                drawText = tempText.substring(0, subPos);
                subTxtW = metrics.stringWidth(drawText);
            }
            graphics2D.drawString(drawText, x, y);
            y += textH;
            textW = textW - subTxtW;
            tempText = tempText.substring(subPos);
        }

        graphics2D.drawString(tempText, x, y);
    }
}
